package com.cos.hospital.ui.main;

import android.Manifest;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;

import com.cos.hospital.code.Code;
import com.cos.hospital.init.BaseActivity;
import com.cos.hospital.model.UHttp;
import com.cos.hospital.model.bean.ApkInfo;
import com.cos.hospital.model.bean.ErrorBean;
import com.cos.hospital.model.bean.ResultBean;
import com.cos.hospital.model.connector.HttpMsgListener;
import com.cos.hospital.model.retrofit.FileWrapper;
import com.cos.hospital.model.retrofit.MyObserver;
import com.cos.hospital.model.retrofit.RequestServes;
import com.cos.hospital.tool.FileUtil;
import com.cos.hospital.tool.UDialog;
import com.cos.hospital.tool.ULog;
import com.cos.hospital.tool.UTxt;
import com.google.gson.JsonObject;
import com.jude.utils.JUtils;
import com.tbruyelle.rxpermissions2.RxPermissions;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;

/**
 * 继承这个类来让Activity获取检测APP版本的能力
 * Created by yby on 2018/12/24
 */
public abstract class CheckAppVersionActivity extends BaseActivity {

    private File apkFile;

    protected void getNewestVersionInfo() {
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("apkClientType", 1);
        jsonObject.addProperty("platformType ", 1);
        jsonObject.addProperty("phoneType", isPad(this) ? 2 : 1);
        UHttp.start(getServes().getApkVersion(jsonObject), "获取APK版本信息", new HttpMsgListener<ResultBean<ApkInfo>>() {
            @Override
            public void onSubscribe(Disposable disposable) {
                addEvent(disposable);
            }

            @Override
            public void onError(String describe) {
                showNotice(describe);
            }

            @Override
            public void onSuccess(ResultBean<ApkInfo> dto) {
                if (dto.isSuccess()) {
                    ApkInfo apkInfo = dto.getResult();
                    if (apkInfo != null) {
                        int apkVersionNo = apkInfo.getApkVersionNo();
                        if (apkVersionNo > JUtils.getAppVersionCode()) {
                            String apkUrl = apkInfo.getApkUrl();
                            String description = apkInfo.getDescription();
                            boolean isForced = apkInfo.isForced();
                            if (isForced) {
                                UDialog.getInstance(context, false, false)
                                    .showNoticeWithOnebtn(description, "立即更新", (result, dia) -> downFile(true, apkUrl, apkVersionNo));
                            } else {
                                UDialog.getInstance(context, true, true)
                                    .showSelectWithTwobtn(description, "立即更新", "下次再说", (result, dia) -> {
                                        downFile(false, apkUrl, apkVersionNo);
                                        dia.dismiss();
                                    }, Dialog::dismiss);
                            }
                        }
                    }
                } else {
                    ErrorBean errorBean = dto.getError();
                    if (errorBean != null) {
                        showNotice(UTxt.isNull(errorBean.getMessage(), Code.DefaultPrompt));
                    } else {
                        showNotice(Code.DefaultPrompt);
                    }
                }
            }
        });
    }

    private void downFile(boolean isForced, String fileUrl, final int apkVersionNo) {
        final ProgressDialog dialog = new ProgressDialog(context);
        dialog.setTitle("正在下载中，请稍后");
        dialog.setMax(100);
        dialog.setCanceledOnTouchOutside(!isForced);
        dialog.setCancelable(!isForced);
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.show();
        RequestServes requestServes = new FileWrapper((total, progress) -> {
            int value = (int) ((float) progress / (float) total * 100f);
            dialog.setProgress(value);
            if (value >= 100) {
                dialog.dismiss();
            }
        }).create(RequestServes.class);
        requestServes.downFile(fileUrl)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new MyObserver<ResponseBody>() {
                @Override
                public void onSubscribe(@NonNull Disposable d) {
                    super.onSubscribe(d);
                    addEvent(d);
                }

                @Override
                public void onError(Throwable e) {
                    super.onError(e);
                    showNotice("安装包下载失败");
                }

                @Override
                public void onNext(@NonNull ResponseBody responseBody) {
                    super.onNext(responseBody);
                    if (responseBody != null) {
                        InputStream inputStream = responseBody.byteStream();
                        String path = FileUtil.getExternalCacheDir(context);
                        String name = apkVersionNo + ".apk";
                        apkFile = new File(path, name);
                        writeToFile(inputStream);
                    }
                }
            });
    }

    private void writeToFile(InputStream inputStream) {
        Observable
            .create((ObservableOnSubscribe<String>) emitter -> {
                try {
                    FileOutputStream fos = new FileOutputStream(apkFile);
                    BufferedInputStream bis = new BufferedInputStream(inputStream);
                    byte[] buffer = new byte[1024];
                    int len;
                    while ((len = bis.read(buffer)) != -1) {
                        fos.write(buffer, 0, len);
                    }
                    fos.flush();
                    fos.close();
                    bis.close();
                    inputStream.close();
                } catch (IOException e) {
                    ULog.d(e.toString());
                }
                emitter.onNext("");
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new MyObserver<String>() {
                @Override
                public void onSubscribe(Disposable d) {
                    addEvent(d);
                }

                @Override
                public void onNext(String s) {
                    checkIsAndroidO();
                }
            });
    }

    /**
     * 判断是否是8.0,8.0需要处理未知应用来源权限问题,否则直接安装
     */
    private void checkIsAndroidO() {
        if (Build.VERSION.SDK_INT >= 26) {
            boolean haveInstallPermission = getPackageManager().canRequestPackageInstalls();
            if (!haveInstallPermission) {
                //请求安装未知应用来源的权限
                RxPermissions rxPermissions = new RxPermissions(this);
                rxPermissions.request(Manifest.permission.REQUEST_INSTALL_PACKAGES)
                    .subscribe(granted -> {
                        if (granted) {
                            installApk(this);
                        } else {
                            Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
                            intent.setData(Uri.fromParts("package", context.getPackageName(), null));
                            startActivityForResult(intent, 10012);
                        }
                    });
            } else {
                installApk(this);
            }
        } else {
            installApk(this);
        }
    }

    /**
     * 安装APK
     */
    public void installApk(Context context) {
        String apkFilePath = apkFile.getPath();
        if (context == null || TextUtils.isEmpty(apkFilePath)) {
            return;
        }
        File file = new File(apkFilePath);
        Intent intent = new Intent(Intent.ACTION_VIEW);

        //判读版本是否在7.0以上
        if (Build.VERSION.SDK_INT >= 24) {
            //provider authorities
            Uri apkUri = FileProvider.getUriForFile(context,  "com.cos.hospital.provider", file);
            //Granting Temporary Permissions to a URI
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        } else {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        }
        context.startActivity(intent);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case 10012:
                checkIsAndroidO();
                break;
        }
    }

    private boolean isPad(Context context) {
        return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration
            .SCREENLAYOUT_SIZE_LARGE;
    }

}
